home *** CD-ROM | disk | FTP | other *** search
/ ASME's Mechanical Engine…ing Toolkit 1997 December / ASME's Mechanical Engineering Toolkit 1997 December.iso / c_lang / sc.zoo / lex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-03  |  11.1 KB  |  558 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Lexical analyser
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *
  10.  */
  11.  
  12.  
  13.  
  14. #if defined(BSD42) || defined(BSD43)
  15. #include <sys/ioctl.h>
  16. #endif 
  17.  
  18. #include <curses.h>
  19. #include <signal.h>
  20. #include <setjmp.h>
  21. #include "sc.h"
  22. #include <ctype.h>
  23.  
  24. #ifdef BSD42
  25. #include <strings.h>
  26. #else
  27. #ifndef SYSIII
  28. #include <string.h>
  29. #endif
  30. #endif
  31.  
  32. #include "y.tab.h"
  33.  
  34. char *strtof();
  35.  
  36. jmp_buf wakeup;
  37. jmp_buf fpe_buf;
  38.  
  39. struct key {
  40.     char *key;
  41.     int val;
  42. };
  43.  
  44. struct key experres[] = {
  45. #include "experres.h"
  46.     0, 0};
  47.  
  48. struct key statres[] = {
  49. #include "statres.h"
  50.     0, 0};
  51.  
  52. #define ctl(x) ('x'&037)
  53.  
  54. yylex () {
  55.     register char *p = line+linelim;
  56.     int ret;
  57.     while (isspace(*p)) p++;
  58.     if (*p==0) ret = -1;
  59.     else if (isalpha(*p)) {
  60.     char *tokenst = p;
  61.     register tokenl;
  62.     register struct key *tblp;
  63.     tokenl = 0;
  64.     /*
  65.      * This picks up either 1 or 2 alpha characters (a column) or
  66.      * tokens with at least three leading alphas and '_' or digits
  67.      * (a function or token or command or a range name)
  68.     */
  69.     while (isalpha(*p) || ((*p == '_') || isdigit(*p)) && (tokenl > 2)) {
  70.         p++;
  71.         tokenl++;
  72.     }
  73.     if (tokenl <= 2) {
  74.         register  col;  /* a COL is 1 or 2 char alpha (and not pi or ln!) */
  75.         if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'i') {
  76.         ret = K_PI;
  77.         } else if (tokenl == 2 && tokenst[0] == 'l' && tokenst[1] == 'n') {
  78.         ret = K_LN;
  79.         } else {
  80.         ret = COL;
  81.         col = ((tokenst[0] & 0137) - 'A');
  82.         if (p == tokenst+2)
  83.             col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
  84.         yylval.ival =  col;
  85.         }
  86.     } else {
  87.         ret = WORD;
  88.         for (tblp = linelim ? experres : statres; tblp->key; tblp++)
  89.             if (((tblp->key[0]^tokenst[0])&0137)==0
  90.              && tblp->key[tokenl]==0) {
  91.             register i = 1;
  92.             while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0)
  93.                 i++;
  94.             if (i>=tokenl) {
  95.                 ret = tblp->val;
  96.                 break;
  97.             }
  98.             }
  99.         if (ret==WORD) { 
  100.         struct range *r;
  101.         if (r = find_range(tokenst, tokenl,
  102.                    (struct ent *)0, (struct ent *)0)) {
  103.             yylval.rval.left = r->r_left;
  104.             yylval.rval.right = r->r_right;
  105.             if (r->r_is_range)
  106.                 ret = RANGE;
  107.             else
  108.             ret = VAR;
  109.         } else {
  110.             linelim = p-line;
  111.             yyerror ("Unintelligible word");
  112.         }
  113.         }
  114.     }
  115.     } else if ((*p == '.') || isdigit(*p)) {
  116.     double v = 0;
  117.     int temp;
  118.     char *nstart = p;
  119.     if (*p != '.') {
  120.         do v = v*10 + (double)(*p-'0');
  121.         while (isdigit(*++p));
  122.     }
  123.     if (*p=='.' || *p == 'e' || *p == 'E') {
  124.         ret = FNUMBER;
  125.         p = strtof(nstart, &yylval.fval);
  126.     } else {
  127.         /* A NUMBER must hold at least MAXROW and MAXCOL */
  128.         /* This is consistent with a short row and col in struct ent */
  129.         if (v > (double)32767 || v < (double)-32768) {
  130.         ret = FNUMBER;
  131.         yylval.fval = v;
  132.         } else {
  133.         temp = (int)v;
  134.         if((double)temp != v) {
  135.             ret = FNUMBER;
  136.             yylval.fval = v;
  137.         } else {
  138.             ret = NUMBER;
  139.             yylval.ival = temp;
  140.         }
  141.         }
  142.     }
  143.     } else if (*p=='"') {
  144.     char *ptr;
  145.         ptr = p+1;
  146.         while(*ptr && *ptr++ != '"');
  147.         ptr = xmalloc((unsigned)(ptr-p));
  148.     yylval.sval = ptr;
  149.     p += 1;
  150.     while (*p && *p!='"') *ptr++ = *p++;
  151.     *ptr = 0;
  152.     if (*p) p += 1;
  153.     ret = STRING;
  154.     } else if (*p=='[') {
  155.     while (*p && *p!=']') p++;
  156.     if (*p) p++;
  157.     linelim = p-line;
  158.     return yylex();
  159.     } else ret = *p++;
  160.     linelim = p-line;
  161.     return ret;
  162. }
  163.  
  164. #ifdef SIMPLE
  165.  
  166. initkbd()
  167. {}
  168.  
  169. kbd_again()
  170. {}
  171.  
  172. resetkbd()
  173. {}
  174.  
  175. nmgetch()
  176. {
  177.     return (getchar() & 0x7f);
  178. }
  179.  
  180. #else /*SIMPLE*/
  181.  
  182. #if defined(BSD42) || defined (SYSIII) || defined(BSD43)
  183.  
  184. #define N_KEY 4
  185.  
  186. struct key_map {
  187.     char *k_str;
  188.     char k_val;
  189.     char k_index;
  190. }; 
  191.  
  192. struct key_map km[N_KEY];
  193.  
  194. char keyarea[N_KEY*10];
  195.  
  196. char *tgetstr();
  197. char *getenv();
  198. char *ks;
  199. char ks_buf[20];
  200. char *ke;
  201. char ke_buf[20];
  202.  
  203. #ifdef TIOCSLTC
  204. struct ltchars old_chars, new_chars;
  205. #endif
  206.  
  207. char dont_use[] = {
  208.     ctl(z), ctl(r), ctl(l), ctl(b), ctl(c), ctl(f), ctl(g), ctl([),
  209.     ctl(h), ctl(m), ctl(j), ctl(n), ctl(p), ctl(q), ctl(s), ctl(t),
  210.     ctl(u), ctl(v), ctl(e), ctl(a), ctl(i), ctl(w), 0,
  211. };
  212.  
  213. charout(c)
  214. int c;
  215. {
  216.     (void)putchar(c);
  217. }
  218.  
  219. initkbd()
  220. {
  221.     register struct key_map *kp;
  222.     register i,j;
  223.     char *p = keyarea;
  224.     char *ktmp;
  225.     static char buf[1024]; /* Why do I have to do this again? */
  226.  
  227.     if (tgetent(buf, getenv("TERM")) <= 0)
  228.     return;
  229.  
  230.     km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl(b);
  231.     km[1].k_str = tgetstr("kr", &p); km[1].k_val = ctl(f);
  232.     km[2].k_str = tgetstr("ku", &p); km[2].k_val = ctl(p);
  233.     km[3].k_str = tgetstr("kd", &p); km[3].k_val = ctl(n);
  234.     ktmp = tgetstr("ks",&p);
  235.     if (ktmp)  {
  236.     (void) strcpy(ks_buf, ktmp);
  237.     ks = ks_buf;
  238.     tputs(ks, 1, charout);
  239.     }
  240.     ktmp = tgetstr("ke",&p);
  241.     if (ktmp)  {
  242.     (void) strcpy(ke_buf, ktmp);
  243.     ke = ke_buf;
  244.     }
  245.  
  246.     /* Unmap arrow keys which conflict with our ctl keys   */
  247.     /* Ignore unset, longer than length 1, and 1-1 mapped keys */
  248.  
  249.     for (i = 0; i < N_KEY; i++) {
  250.     kp = &km[i];
  251.     if (kp->k_str && (kp->k_str[1] == 0) && (kp->k_str[0] != kp->k_val))
  252.         for (j = 0; dont_use[j] != 0; j++)
  253.             if (kp->k_str[0] == dont_use[j]) {
  254.              kp->k_str = (char *)0;
  255.              break;
  256.         }
  257.     }
  258.  
  259.  
  260. #ifdef TIOCSLTC
  261.     (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars);
  262.     new_chars = old_chars;
  263.     if (old_chars.t_lnextc == ctl(v))
  264.     new_chars.t_lnextc = -1;
  265.     if (old_chars.t_rprntc == ctl(r))
  266.     new_chars.t_rprntc = -1;
  267.     (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
  268. #endif
  269. }
  270.  
  271. kbd_again()
  272. {
  273.     if (ks) 
  274.     tputs(ks, 1, charout);
  275.  
  276. #ifdef TIOCSLTC
  277.     (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
  278. #endif
  279. }
  280.  
  281. resetkbd()
  282. {
  283.     if (ke) 
  284.     tputs(ke, 1, charout);
  285.  
  286. #ifdef TIOCSLTC
  287.     (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars);
  288. #endif
  289. }
  290.  
  291. nmgetch() 
  292. {
  293.     register int c;
  294.     register struct key_map *kp;
  295.     register struct key_map *biggest;
  296.     register int i;
  297.     int almost;
  298.     int maybe;
  299.  
  300.     static char dumpbuf[10];
  301.     static char *dumpindex;
  302.  
  303. #ifdef SYSV3
  304.     void timeout();
  305. #else
  306.     int timeout();
  307. #endif
  308.  
  309.     if (dumpindex && *dumpindex)
  310.         return (*dumpindex++);
  311.  
  312.     c = getchar() & 0x7f;
  313.     biggest = 0;
  314.     almost = 0;
  315.  
  316.     for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
  317.     if (!kp->k_str)
  318.         continue;
  319.     if (c == kp->k_str[kp->k_index]) {
  320.         almost = 1;
  321.         kp->k_index++;
  322.         if (kp->k_str[kp->k_index] == 0) {
  323.         c = kp->k_val;
  324.                    for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  325.                 kp->k_index = 0;
  326.             return(c);
  327.         }
  328.     }
  329.     if (!biggest && kp->k_index)
  330.         biggest = kp;
  331.         else if (kp->k_index && biggest->k_index < kp->k_index)
  332.         biggest = kp;
  333.     }
  334.  
  335.     if (almost) { 
  336.  
  337.         (void) signal(SIGALRM, timeout);
  338.         (void) alarm(1);
  339.  
  340.     if (setjmp(wakeup) == 0) { 
  341.         maybe = nmgetch();
  342.         (void) alarm(0);
  343.         return(maybe);
  344.     }
  345.  
  346.     }
  347.     
  348.     if (biggest) {
  349.     for (i = 0; i<biggest->k_index; i++) 
  350.         dumpbuf[i] = biggest->k_str[i];
  351.     dumpbuf[i++] = c;
  352.     dumpbuf[i] = 0;
  353.     dumpindex = &dumpbuf[1];
  354.            for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  355.         kp->k_index = 0;
  356.     return (dumpbuf[0]);
  357.     }
  358.  
  359.     return(c);
  360. }
  361.  
  362. #endif
  363.  
  364. #if defined(SYSV2) || defined(SYSV3)
  365.  
  366. initkbd()
  367. {
  368.     keypad(stdscr, TRUE);
  369. }
  370.  
  371. kbd_again()
  372. {
  373.     keypad(stdscr, TRUE);
  374. }
  375.  
  376. resetkbd()
  377. {
  378.     keypad(stdscr, FALSE);
  379. }
  380.  
  381. nmgetch()
  382. {
  383.     register int c;
  384.  
  385.     c = getch();
  386.     switch (c) {
  387.     case KEY_LEFT:  c = ctl(b); break;
  388.     case KEY_RIGHT: c = ctl(f); break;
  389.     case KEY_UP:    c = ctl(p); break;
  390.     case KEY_DOWN:  c = ctl(n); break;
  391.     default:   c = c & 0x7f; 
  392.     }
  393.     return (c);
  394. }
  395.  
  396. #endif /* SYSV2 || SYSV3 */
  397.  
  398. #endif /* SIMPLE */
  399.  
  400. #ifdef SYSV3
  401. void
  402. #endif
  403. timeout()
  404. {
  405.     longjmp(wakeup, -1);
  406. }
  407.  
  408. int dbline;
  409.  
  410. /*VARARGS*/
  411. void
  412. debug (str)
  413. char *str;
  414. {
  415.     (void) mvprintw (2+(dbline++%22),80-70,str);
  416.     (void) clrtoeol();
  417. }
  418.  
  419. #ifdef SYSV3
  420. void
  421. #endif
  422. fpe_trap()
  423. {
  424.     longjmp(fpe_buf, 1);
  425. }
  426.  
  427. /*
  428.  * This converts a floating point number of the form
  429.  * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
  430.  * to floating point. 
  431.  * p is advanced.
  432.  */
  433.  
  434. char *
  435. strtof(p, res)
  436. register char *p;
  437. double *res;
  438. {
  439.     double acc;
  440.     int sign;
  441.     double fpos;
  442.     int exp;
  443.     int exps;
  444. #ifdef SYSV3
  445.     void quit();
  446. #else
  447.     int quit();
  448. #endif
  449.  
  450.     (void) signal(SIGFPE, fpe_trap);
  451.     if (setjmp(fpe_buf)) {
  452.     error("Floating point exception\n");
  453.     *res = 0.0; 
  454.         (void) signal(SIGFPE, quit);
  455.     return(p);
  456.     }
  457.     acc = 0.0;
  458.     sign = 1;
  459.     exp = 0;
  460.     exps = 1;
  461.     if (*p == '+')
  462.         p++;
  463.     else if (*p == '-') {
  464.         p++;
  465.         sign = -1;
  466.     }
  467.     while (isdigit(*p)) {
  468.         acc = acc * 10.0 + (double)(*p - '0');
  469.         p++;
  470.     }
  471.     if (*p == 'e' || *p == 'E') {
  472.         p++;
  473.         if (*p == '+')
  474.         p++;
  475.         else if (*p == '-') {
  476.         p++;
  477.         exps = -1;
  478.         }
  479.         while(isdigit(*p)) {
  480.         exp = exp * 10 + (*p - '0');
  481.         p++;
  482.         }
  483.     }
  484.     if (*p == '.') {
  485.     fpos = 1.0/10.0;
  486.     p++;
  487.     while(isdigit(*p)) {
  488.         acc += (*p - '0') * fpos;
  489.         fpos *= 1.0/10.0;
  490.         p++;
  491.     }
  492.     }
  493.     if (*p == 'e' || *p == 'E') {
  494.     exp = 0;
  495.     exps = 1;
  496.         p++;
  497.     if (*p == '+')
  498.         p++;
  499.     else if (*p == '-') {
  500.         p++;
  501.         exps = -1;
  502.     }
  503.     while(isdigit(*p)) {
  504.         exp = exp * 10 + (*p - '0');
  505.         p++;
  506.     }
  507.     }
  508.     if (exp) {
  509.     if (exps > 0)
  510.         while (exp--)
  511.         acc *= 10.0;
  512.     else
  513.         while (exp--)
  514.         acc *= 1.0/10.0;
  515.     }
  516.     if (sign > 0)
  517.         *res = acc;
  518.     else
  519.     *res = -acc;
  520.  
  521.     (void) signal(SIGFPE, quit);
  522.     return(p);
  523. }
  524.  
  525. help () {
  526.     (void) move(1,0);
  527.     (void) clrtobot();
  528.     dbline = 0;
  529.     debug ("Cursor:     ^n j next row       ^p k prev. row  ESC ^g erase cmd");
  530.     debug ("            ^f l fwd col        ^b h back col    ^l ^r redraw screen");
  531.     debug ("               w fwd to next       b back to next   ^e <dir> end");
  532.     debug ("               0 col A             $ last col        g goto ");
  533.     debug ("               ^ row 0             # last row");
  534.     debug ("Cell:      \" < > enter label       = enter value     x clear cell");
  535.     debug ("               c copy cell         m mark cell      ^t line 1 on/off");  
  536.     debug ("              ^a type value       ^w type expr.     ^v type vbl name");
  537.     debug ("Row, Col:  ar ac dup           ir ic insert      sr sc show");
  538.     debug ("           dr dc delete        zr zc hide        pr pc pull");
  539.     debug ("           vr vc value only        f format");
  540.     debug ("Ranges:       /u undefine range   /s show ranges    /d define range");
  541.     debug ("              /c copy range       /x clear range    /f fill range");
  542.     debug ("              /v values only");
  543.     debug ("File:          G get database      M merge database  T write tbl fmt");
  544.     debug ("               P put database      W write listing   R run macros");
  545.     debug ("               D define directory");
  546.     debug ("Misc:        Q q quit             pm pull (merge)");
  547.     debug ("Expr:      +-*/^ arithmetic     ?e:e conditional   & | booleans");
  548.     debug ("           < = > relations     <= >= relations      != relations");
  549.     debug ("                 @sum(range)         @avg(range)       @prod(range)");
  550.     debug ("                 @func(e) - lots of other math functions");
  551.     error("Hit any key to continue ");
  552.     (void) refresh();
  553.     (void) nmgetch();
  554.     FullUpdate++;
  555.     (void) move(1,0);
  556.     (void) clrtobot();
  557. }
  558.